package com.diandiji.demo.interceptor;

import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.diandiji.demo.config.JwtConfig;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * 自定义拦截器，用于验证用户请求中的 Token 是否有效。
 * 如果 Token 缺失、格式错误或无效，将抛出异常并阻止请求继续执行。
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {

    /**
     * 在请求处理之前执行的拦截逻辑。
     *
     * @param request  当前 HTTP 请求对象
     * @param response 当前 HTTP 响应对象
     * @param handler  被调用的处理器对象
     * @return 如果返回 true，则继续执行后续逻辑；如果返回 false，则中断请求
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 从请求头中获取 Token
        String token = request.getHeader("Authorization");
        System.out.println("[拦截器日志] 请求头中的 Token：" + token);
        // 校验 Token 格式
        if (token == null || !token.startsWith("Bearer ")) {
            // 如果 Token 缺失或格式错误，抛出异常
            System.out.println("[拦截器日志] Token 缺失或格式错误"); // 添加日志
            throw new IllegalArgumentException("Token 缺失或格式错误");
        }

        // 解析 Token
        String jwtToken = token.substring(7);
        Integer userId = parseTokenToUserId(jwtToken);
        System.out.println("[拦截器日志] 解析后的用户 ID：" + userId);

        if (userId == null) {
            // 如果 Token 无效或已过期，抛出异常
            System.out.println("[拦截器日志] Token 无效或已过期");
            throw new IllegalArgumentException("Token 无效或已过期");
        }

        // 将用户 ID 设置到请求属性中，供后续逻辑使用
        request.setAttribute("currentUserId", userId);
        return true;
    }

    /**
     * 模拟 Token 解析方法（需根据实际 JWT 库实现）。
     * 当前实现仅返回一个示例值，实际项目中应使用 JWT 库解析 Token。
     *
     * @param token 待解析的 Token 字符串
     * @return 解析后的用户 ID，如果解析失败则返回 null
     */
    private Integer parseTokenToUserId(String token) {
        try {
            DecodedJWT jwt = JwtConfig.verifyToken(token);  // 验证并解析 Token
            return jwt.getClaim("userId").asInt();
        } catch (JWTDecodeException e) {
            return null;
        }
    }
}